#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "storage_system.h"
#include "cache_manager.h"
#include "page_manager.h"
#include "disk_io.h"
#include "catalog.h"
#include "lexer.h"
#include "parser.h"
#include "semantic_analyzer.h"
#include "plan_generator.h"

// 测试统计变量
int total_tests = 0;
int page_storage_success = 0;
int cache_mechanism_success = 0;
int interface_integration_success = 0;

// 打印测试结果的辅助函数
void print_test_result(const char* test_name, int success) {
    printf("%s: %s\n", test_name, success ? "PASS" : "FAIL");
}

// 测试页式存储系统功能
void test_page_storage() {
    total_tests++;
    printf("\n=== 2.1 页式存储系统测试 ===\n");
    printf("功能要求：页大小固定（如4KB）\n");
    printf("          支持页的分配、释放、读写\n");
    printf("          提供接口：read_page(page_id), write_page(page_id, data)\n");
    
    int current_success = 1;
    
    // 初始化存储系统
    if (init_storage_system("./data") != STORAGE_OK) {
        printf("错误: 初始化存储系统失败\n");
        current_success = 0;
    } else {
        printf("页大小: %d 字节\n", PAGE_SIZE);
        
        // 测试页分配
        page_id_t page_id = allocate_page();
        printf("分配的页ID: %d\n", page_id);
        
        if (page_id == UINT32_MAX) {
            printf("错误: 页分配失败\n");
            current_success = 0;
        } else {
            // 测试页写入
            char test_data[PAGE_SIZE];
            memset(test_data, 0, PAGE_SIZE);
            strcpy(test_data, "测试页存储系统的数据");
            
            storage_error_t write_result = write_page(page_id, (const uint8_t*)test_data);
            if (write_result == STORAGE_OK) {
                printf("页写入成功\n");
            } else {
                printf("错误: 页写入失败，错误代码 %d\n", write_result);
                current_success = 0;
            }
            
            // 测试页读取
            uint8_t read_buffer[PAGE_SIZE];
            storage_error_t read_result = read_page(page_id, read_buffer);
            
            if (read_result == STORAGE_OK) {
                printf("页读取成功\n");
                printf("读取的数据: %s\n", read_buffer);
                
                // 验证数据一致性
                if (memcmp(test_data, read_buffer, strlen(test_data) + 1) == 0) {
                    printf("数据验证成功\n");
                } else {
                    printf("错误: 数据验证失败\n");
                    current_success = 0;
                }
            } else {
                printf("错误: 页读取失败，错误代码 %d\n", read_result);
                current_success = 0;
            }
            
            // 测试页释放
            storage_error_t free_result = free_page(page_id);
            if (free_result == STORAGE_OK) {
                printf("页释放成功\n");
            } else {
                printf("错误: 页释放失败，错误代码 %d\n", free_result);
                current_success = 0;
            }
        }
        
        // 关闭存储系统
        shutdown_storage_system();
    }
    
    if (current_success) {
        page_storage_success++;
    }
    
    printf("\n=== 2.1 页式存储系统测试完成 ===\n");
}

// 测试缓存机制功能
void test_cache_mechanism() {
    total_tests++;
    printf("\n=== 2.2 缓存机制测试 ===\n");
    printf("功能要求：实现页缓存（如LRU或FIFO）\n");
    printf("          支持缓存命中统计、替换日志\n");
    printf("          提供接口：get_page(page_id), flush_page(page_id)\n");
    
    int current_success = 1;
    
    // 初始化存储系统
    if (init_storage_system("./data") != STORAGE_OK) {
        printf("错误: 初始化存储系统失败\n");
        current_success = 0;
    } else {
        // 分配多个页面并写入数据
        const int NUM_PAGES = 20; // 超过缓存大小(CACHE_SIZE=16)
        page_id_t page_ids[NUM_PAGES];
        char page_data[NUM_PAGES][64];
        
        printf("缓存大小: %d 页\n", CACHE_SIZE);
        printf("分配并写入 %d 个页面（用于测试缓存替换）...\n", NUM_PAGES);
        
        for (int i = 0; i < NUM_PAGES; i++) {
            page_ids[i] = allocate_page();
            if (page_ids[i] == UINT32_MAX) {
                printf("错误: 页面 %d 分配失败\n", i);
                current_success = 0;
                continue;
            }
            
            sprintf(page_data[i], "页面 %d 的数据", i);
            char full_page_data[PAGE_SIZE];
            memset(full_page_data, 0, PAGE_SIZE);
            strcpy(full_page_data, page_data[i]);
            
            if (write_page(page_ids[i], (const uint8_t*)full_page_data) != STORAGE_OK) {
                printf("错误: 页面 %d 写入失败\n", i);
                current_success = 0;
            }
        }
        
        // 缓存测试部分 - 第一次读取所有页面，这些页面会被加载到缓存中
        printf("\n第一次读取页面以加载到缓存...\n");
        for (int i = 0; i < NUM_PAGES; i++) {
            uint8_t buffer[PAGE_SIZE];
            if (get_page(page_ids[i], buffer) != STORAGE_OK) {
                printf("错误: 页面 %d 读取失败\n", i);
                current_success = 0;
            }
        }
        
        // 打印第一次读取后的缓存统计
        printf("\n第一次读取后缓存统计信息:\n");
        printf("缓存命中次数: %d\n", get_cache_hits());
        printf("缓存未命中次数: %d\n", get_cache_misses());
        
        // 缓存测试部分 - 第二次读取相同页面，应该会有缓存命中
        printf("\n第二次读取页面以测试缓存命中...\n");
        // 由于缓存大小为16，而我们读取了20个页面，所以前4个页面应该已经被替换出缓存
        for (int i = 4; i < NUM_PAGES; i++) {
            uint8_t buffer[PAGE_SIZE];
            if (get_page(page_ids[i], buffer) != STORAGE_OK) {
                printf("错误: 页面 %d 读取失败\n", i);
                current_success = 0;
            }
        }
        
        // 打印第二次读取后的缓存统计（整体统计）
        printf("\n总体缓存统计信息:\n");
        printf("缓存命中次数: %d\n", get_cache_hits());
        printf("缓存未命中次数: %d\n", get_cache_misses());
        
        // 刷新特定页面
        if (page_ids[0] != UINT32_MAX) {
            if (flush_page(page_ids[0]) == STORAGE_OK) {
                printf("\n页面 %d 刷新成功\n", page_ids[0]);
            } else {
                printf("\n错误: 页面 %d 刷新失败\n", page_ids[0]);
                current_success = 0;
            }
        }
        
        // 刷新所有页面
        if (flush_all_pages() == STORAGE_OK) {
            printf("所有页面刷新成功\n");
        } else {
            printf("错误: 刷新所有页面失败\n");
            current_success = 0;
        }
        
        // 释放所有页面
        for (int i = 0; i < NUM_PAGES; i++) {
            if (page_ids[i] != UINT32_MAX) {
                free_page(page_ids[i]);
            }
        }
        
        // 关闭存储系统
        shutdown_storage_system();
    }
    
    if (current_success) {
        cache_mechanism_success++;
    }
    
    printf("\n=== 2.2 缓存机制测试完成 ===\n");
}

// 测试接口与集成功能
void test_storage_interface() {
    total_tests++;
    printf("\n=== 2.3 接口与集成测试 ===\n");
    printf("功能要求：提供统一存储访问接口\n");
    printf("          与执行计划对接，支持物理数据访问\n");
    
    int current_success = 1;
    
    // 初始化存储系统
    if (init_storage_system("./data") != STORAGE_OK) {
        printf("错误: 初始化存储系统失败\n");
        current_success = 0;
    } else {
        // 移除对不存在的create_system_pages()函数的调用
        // 系统表页面的初始化已经在init_storage_system函数中完成
        
        // 引导系统表
        if (catalog_bootstrap() != 0) {
            printf("错误: 模式目录引导失败\n");
            current_success = 0;
        } else {
            // 创建内存目录
            Catalog* catalog = create_catalog();
            if (!catalog) {
                printf("错误: 创建模式目录失败\n");
                current_success = 0;
            } else {
                // 创建表（测试与存储系统的集成）
                char* create_sql = "CREATE TABLE interface_test (id INT, name VARCHAR(50));";
                printf("\n执行: %s\n", create_sql);
                
                Lexer* lexer = create_lexer(create_sql);
                Parser* parser = create_parser(lexer);
                ASTNode* ast = parse_statement(parser);
                
                if (ast) {
                    printf("语法分析成功\n");
                    
                    // 语义分析
                    SemanticResult sem_result = analyze_semantics(ast, catalog);
                    if (sem_result.success) {
                        printf("语义分析成功\n");
                        
                        // 生成执行计划（测试与存储系统的对接）
                        PlanNode* plan = generate_plan(ast, catalog);
                        if (plan) {
                            printf("执行计划生成成功\n");
                            free_plan(plan);
                        } else {
                            printf("错误: 执行计划生成失败\n");
                            current_success = 0;
                        }
                    } else {
                        printf("错误: 语义分析失败: %s\n", sem_result.error_message);
                        free(sem_result.error_message);
                        current_success = 0;
                    }
                    
                    free_ast_node(ast);
                } else {
                    printf("错误: 语法分析失败\n");
                    current_success = 0;
                }
                
                free_parser(parser);
                free_lexer(lexer);
                free_catalog(catalog);
            }
        }
        
        // 关闭存储系统
        shutdown_storage_system();
    }
    
    if (current_success) {
        interface_integration_success++;
    }
    
    printf("\n=== 2.3 接口与集成测试完成 ===\n");
}

// 测试统计变量
// 在文件顶部添加测试重置函数
void reset_test_stats() {
    total_tests = 0;
    page_storage_success = 0;
    cache_mechanism_success = 0;
    interface_integration_success = 0;
}

// 在main函数开始处调用
int main() {
    // 设置中文编码
    system("chcp 65001");
    
    // 重置测试统计
    reset_test_stats();
    
    printf("=== 存储系统综合测试 ===\n\n");
    
    // 运行各项测试
    test_page_storage();        // 测试页式存储系统
    test_cache_mechanism();     // 测试缓存机制
    test_storage_interface();   // 测试接口与集成
    
    printf("\n=== 所有存储系统测试用例执行完毕 ===\n");
    
    // 输出测试总结
    printf("\n=== 测试总结 ===\n");
    printf("总测试用例数: %d\n", total_tests);
    printf("页式存储系统成功率: %d/%d (%.1f%%)\n", 
           page_storage_success, 1, (float)page_storage_success/1*100);
    printf("缓存机制成功率: %d/%d (%.1f%%)\n", 
           cache_mechanism_success, 1, (float)cache_mechanism_success/1*100);
    printf("接口与集成成功率: %d/%d (%.1f%%)\n", 
           interface_integration_success, 1, (float)interface_integration_success/1*100);
    
    // 计算更准确的总体完成度
    int total_success_metrics = 0;
    int total_possible_metrics = 0;
    
    // 页式存储系统测试指标 (5个指标)
    if (page_storage_success) total_success_metrics += 5;
    total_possible_metrics += 5;
    
    // 缓存机制测试指标 (4个指标)
    if (cache_mechanism_success) total_success_metrics += 4;
    total_possible_metrics += 4;
    
    // 接口与集成测试指标 (3个指标)
    if (interface_integration_success) total_success_metrics += 3;
    total_possible_metrics += 3;
    
    printf("\n总体完成度: %.1f%%\n", 
           (float)total_success_metrics/total_possible_metrics*100);
    
    // 暂停以便查看结果
    system("pause");
    
    return 0;
}